#include "IniConfig.h"

#include <QCoreApplication>
#include <QDebug>
#include <QDir>
#include <QFileInfo>
#include <QMutexLocker>

// 静态成员初始化
IniConfig* IniConfig::m_instance = nullptr;
QMutex IniConfig::m_mutex;

IniConfig::IniConfig(QObject* parent) : QObject(parent), m_settings(nullptr)
{
    // 自动设置默认配置文件路径
    QString defaultConfigPath = QCoreApplication::applicationDirPath() + "/config/app_config.ini";
    m_configFilePath = defaultConfigPath;

    // 确保配置目录存在
    QFileInfo fileInfo(m_configFilePath);
    QDir dir = fileInfo.absoluteDir();
    if (!dir.exists()) {
        dir.mkpath(".");
    }

    // 创建配置文件
    m_settings = new QSettings(m_configFilePath, QSettings::IniFormat, this);
    m_settings->setIniCodec("UTF-8");  // 设置编码为UTF-8

    qDebug() << "IniConfig: 自动设置配置文件路径为:" << m_configFilePath;
}

IniConfig::~IniConfig()
{
    if (m_settings) {
        m_settings->sync();  // 确保配置保存
    }
}

IniConfig* IniConfig::instance()
{
    if (m_instance == nullptr) {
        QMutexLocker locker(&m_mutex);
        if (m_instance == nullptr) {
            m_instance = new IniConfig();
        }
    }
    return m_instance;
}

void IniConfig::setConfigFile(const QString& filePath)
{
    QMutexLocker locker(&m_settingsMutex);

    if (m_configFilePath == filePath) {
        return;  // 路径相同，无需更改
    }

    // 保存当前配置
    if (m_settings) {
        m_settings->sync();
        delete m_settings;
    }

    m_configFilePath = filePath;

    // 确保目录存在
    QFileInfo fileInfo(filePath);
    QDir dir = fileInfo.absoluteDir();
    if (!dir.exists()) {
        dir.mkpath(".");
    }

    // 创建新的QSettings实例
    m_settings = new QSettings(m_configFilePath, QSettings::IniFormat, this);
    m_settings->setIniCodec("UTF-8");

    qDebug() << "IniConfig: 配置文件路径设置为:" << m_configFilePath;
}

QString IniConfig::configFile() const
{
    QMutexLocker locker(&m_settingsMutex);
    return m_configFilePath;
}

QVariant IniConfig::value(const QString& key, const QVariant& defaultValue) const
{
    QMutexLocker locker(&m_settingsMutex);
    if (!m_settings) {
        return defaultValue;
    }
    return m_settings->value(key, defaultValue);
}

void IniConfig::setValue(const QString& key, const QVariant& value)
{
    QMutexLocker locker(&m_settingsMutex);
    if (!m_settings) {
        return;
    }

    QVariant oldValue = m_settings->value(key);
    m_settings->setValue(key, value);

    // 如果值发生变化，发出信号
    if (oldValue != value) {
        emit valueChanged(key, value);
    }
}

QString IniConfig::getString(const QString& key, const QString& defaultValue) const
{
    return value(key, defaultValue).toString();
}

int IniConfig::getInt(const QString& key, int defaultValue) const
{
    return value(key, defaultValue).toInt();
}

bool IniConfig::getBool(const QString& key, bool defaultValue) const
{
    return value(key, defaultValue).toBool();
}

double IniConfig::getDouble(const QString& key, double defaultValue) const
{
    return value(key, defaultValue).toDouble();
}

void IniConfig::setString(const QString& key, const QString& value) { setValue(key, value); }

void IniConfig::setInt(const QString& key, int value) { setValue(key, value); }

void IniConfig::setBool(const QString& key, bool value) { setValue(key, value); }

void IniConfig::setDouble(const QString& key, double value) { setValue(key, value); }

bool IniConfig::contains(const QString& key) const
{
    QMutexLocker locker(&m_settingsMutex);
    if (!m_settings) {
        return false;
    }
    return m_settings->contains(key);
}

void IniConfig::remove(const QString& key)
{
    QMutexLocker locker(&m_settingsMutex);
    if (!m_settings) {
        return;
    }
    m_settings->remove(key);
}

QStringList IniConfig::childGroups() const
{
    QMutexLocker locker(&m_settingsMutex);
    if (!m_settings) {
        return QStringList();
    }
    return m_settings->childGroups();
}

QStringList IniConfig::childKeys(const QString& group) const
{
    QMutexLocker locker(&m_settingsMutex);
    if (!m_settings) {
        return QStringList();
    }

    if (!group.isEmpty()) {
        m_settings->beginGroup(group);
        QStringList keys = m_settings->childKeys();
        m_settings->endGroup();
        return keys;
    }

    return m_settings->childKeys();
}

void IniConfig::sync()
{
    QMutexLocker locker(&m_settingsMutex);
    if (m_settings) {
        m_settings->sync();
    }
}

void IniConfig::clear()
{
    QMutexLocker locker(&m_settingsMutex);
    if (m_settings) {
        m_settings->clear();
    }
}